﻿#pragma once

#include <QtWidgets/QMainWindow>
#include "ui_VisionMainWnd.h"

#include <qgraphicsview>
#include "QGView.h"
#include "DockManager.h"
#include "QThumbnailList.h"

#include "DebugWin.h"
#include <QPixmap>
#include <QLabel>
//#include "IInfer.h"
#include "CameraDef.h"
#include <QLibrary>
#include <QMutex>
#include <QWaitCondition>

namespace cv
{
    class Mat;
    class VideoCapture;
}
namespace XCamera
{
    class ICamera;
}

class HikNetCamera;
class InspectLL;
class ModbusPoll;
class RectangleItem;

enum state_vision {
    ready_stat = 0,     // 待机状态：启动后等待消息
    calib_stat,         // 标定状态：当寄存器00003寄存器为1时
    calib_manu_stat,    // 手动标定
    working_stat        // 工作中状态：正常工作状态
};

// 共享数据结构
struct FrameControl {
    QMutex mutex;
    QWaitCondition cond;
};

class IInfer;
class VisionMainWnd : public QMainWindow
{
    Q_OBJECT

public:
    VisionMainWnd(QWidget *parent = nullptr);
    ~VisionMainWnd();

    InspectLL* getInspect() const { return inspect_; }
    IInfer* getInferPtr() { return infer_objDetect_; }
    QGView* getViews() { return views_; }
    double getExeTime(int cam);

    void drawResults();
    void showRoiRect(bool show);
    RectangleItem* getRoiRectItem();

    virtual void closeEvent(QCloseEvent *event);

    XCamera::ICamera* getCamera() { return camera_; }
    void grabImage(cv::Mat& img);
    void startGrab();
    void stopGrab();
    // pause grab
    void pauseGrab(bool pause) { pauseGrab_ = pause; }
    bool isPauseGrab() { return pauseGrab_; }

    ModbusPoll* getModbusPoll() { return mbPoll_; }


    // 采集处理线程
    bool grabThreadRuning_ = false;
    void grabProcessThread();
    void startGrabThread(); // 启动采集线程：这里采用软触发方式
    void stopGrabThread() { grabThreadRuning_ = false; }    // 停止采集线程
    void pauseGrabThread()  {}
    bool isGrabThreadRunning() { return grabThreadRuning_; }

    bool sendResultToRobot();


    void setGrabFrames(double frmRate) { frameRate_ = frmRate; }
    double getFrmRate() { return frameRate_; };

    void setSrcImage(QImage& src);

    // 相机采集回调函数
    static void cam1GrabCallback(std::string camName, cv::Mat *imgData, void* context);
    void updateLogs(std::string infos);

    // 根据登录用户刷新UI
    void updateUIByUser();

    void userChange();  // 用户切换

    // 状态栏显示信息
    void showMessage(std::string msg);

    bool isEnableInsp();

    void setState(state_vision stat) { sysStat_ = stat; };
    state_vision getState() { return state_vision(sysStat_); }

    QThumbnailList* getThumbnailList() { return thumbList_; }
    void setThumbnailCount(int count);

    // modbus读取失败时，界面容易卡顿，将操作函数放到线程运行
    void heartBeat();
    void checkRobotState();    

    void showImage(cv::Mat src, bool update = true);
    void showImage(QImage src, bool update=true);
    void showImageAddThumbnail(cv::Mat src, bool addThumb);


    void setSaveOneFrame(bool save = true) { saveOneFrame_ = save; }
    bool isSaveOneFrame() { return saveOneFrame_; }
    void saveOneImage(cv::Mat img);

    // 该函数只执行一次，程序启动后，检测到机器人连接成功，启动相机和检测，处于待检测状态
    void startCameraAndInspect();

    void writeResult();

    QToolButton* createToolBtn(QString objName, QString btnText, QString iconPath, QSize sz = QSize(28, 28));

signals:
    void trig_process(uchar* data, int w, int h, int ch);
    void send_fps(double fps);
    void update_ui(cv::Mat src, bool addThumb);
    
    void startup_process(cv::Mat src);

protected:
    void init();
    void initToolbar();
    void initDockWidget();
    void initCamera();
    void initDevice();

    void initVisionAndRobot();

    void saveImage(cv::Mat& src);

private:
    // 界面布局保存与恢复
    void restoreLayout();
    void saveLayout();

    // 创建文件目录：日志文件，关键图像目录，图像保存目录
    void createDir();

    // 操作按钮使能
    void enableToolbarBtn(bool enable);

public slots:

    // toolbar
    void on_startInspect();
    void on_stopInspect();
    void on_openDatabase();

    void on_setParams();    // 修改界面参数后调用

    void on_restoreUI();
    void on_loginDialog();

    void on_receiveImage(QImage img);

    void process(uchar* data, int w, int h, int ch);
    void process_offline(cv::Mat src);
    void Process_infer(cv::Mat& src);

    void on_keyEvent();

    void on_cameraStat(bool connected);
    void on_robot_connect_stat(bool connected);
    void on_product_line_state(bool running);


    void on_showVideo(uchar* data, int w, int h, int steps);
    void on_showFPs(double fps);
    void on_showProTime(double t);

    void on_CamCapture();

    // 定时监控
    void on_monitorTimeOut();
    // plc心跳定时器
    void on_heartBeatTimeOut();
    // 查询机器人抓取是否完成：轮询间隔小一些
    void on_checkRobotStatTimeOut();

    void on_reconnect();

    void on_outputProcessInfo(double proTime, int imageCount);

    // 显示处理结果图像槽函数，并且根据判据结果进行缓存
    void on_show_image(cv::Mat, bool save);

    void on_show_image_thumbnail(cv::Mat src, bool addThumb);

private:
    InspectLL* inspect_ = nullptr;
    IInfer* infer_objDetect_ = nullptr;
    Ui::VisionMainWndClass ui;

    QLibrary camLib_;
    XCamera::ICamera* camera_ = nullptr;
    bool pauseGrab_ = false;            // 采集暂停
    bool stopGrabThread_ = true;
    double frameRate_ = 4;              // 帧率：每秒采集多少帧
    ModbusPoll* mbPoll_ = nullptr;

    bool exitGrabThread_ = true;   // 退出采集线程
    bool enableInspect_ = false;
    int sysStat_ = -1;      // 系统状态
    int calib_image_count_ = 0;
    

    QThumbnailList* thumbList_ = nullptr;

    double inferTime_ = 0.0;
    int64 startTime_ = 0;
    int64 image_count_ = 0;
    int64 pre_image_count_ = 0;

    ads::CDockManager* dockManager_ = nullptr;

    // 定时器
    QTimer* chkRobotTimer_ = nullptr;
    // 心跳程序，写寄存器失败次数
    int writeHBRegFailedCount_ = 0;

    // graphicsView
    RectangleItem* roiItem_ = nullptr;
    QGView* views_ = nullptr;
    QImage srcImage_;
    bool saveOneFrame_ = false;

    QLabel* labelVision_ = nullptr;     // 系统运行状态（暂且未用）：等待信号、停止状态
    QLabel* labelCamStat_ = nullptr;    // 相机状态：链接，断开
    QLabel* labelRobotStat_ = nullptr;   // 机器人状态：运行中-绿灯，停止或者故障-红灯
    QLabel* labelProduceLineStat_ = nullptr;    // 产线状态显示：运行中-绿灯，停机-红灯
    QLabel* labelUser_ = nullptr;   // 当前用户：操作工，管理员，超级用户
    QLabel* labelFPS_ = nullptr;    // 显示帧率  
    QLabel* labelProTime_ = nullptr;  // 处理时间
    

    QIcon* grabbingIcon_ = nullptr;
    QIcon* pauseGrabIcon_ = nullptr;
    QToolButton* camBtn_ = nullptr;

    QPixmap connectedIcon_;
    // 红黄蓝三色灯
    QPixmap greenLight_;
    QPixmap redLight_;
    QPixmap yellowLight_;

    // 定时器管理
    QTimer* checkRobotTimer_ = nullptr;

    bool robot_init_suc_ = false;
    bool vision_init_suc_ = false;
    bool isPLRunning_ = false;
    bool robotReady_ = false;

    bool connect_modbus_ = false;
};
